﻿// #define debug

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;

namespace SenrobControl
{
    public partial class SubForm : Form
    {

        System.Diagnostics.Stopwatch sw;
        string title;
        Point leftTop = new Point(0, 0);
        float ratio = 0;
        Font f = new Font(FontFamily.GenericMonospace, 10);
        Brush b = Brushes.Black;
        PointF p = new PointF(0, 0), p2 = new PointF(0, 12), p3 = new PointF(0, 24), p4 = new PointF(0, 36), p5 = new PointF(0, 48), p6 = new PointF(0, 60);
        double res = 0;
        int countres = 0;
        int countpaint = 0;
        int countframe = 0;
        int missedFrame = 0;
        Thread paintThread;
        Graphics g;
        bool frameAvail = false;

        public SubForm(string title)
        {
            InitializeComponent();
            // this.panel1.Paint += new PaintEventHandler(panel1_Paint);
            // this.Paint += new PaintEventHandler(SubForm_Paint);
            this.g = this.CreateGraphics();
            paintThread = newPaintThread();
            this.Resize += new EventHandler(SubForm_Resize);
            this.Text = title;
            sw = new Stopwatch();
        }

        private Thread newPaintThread()
        {
            Thread t = new Thread(paintLoop);
            t.Priority = ThreadPriority.Normal;
            t.IsBackground = true;
            return t;
        }
        public void paintLoop()
        {
            while (this.Visible)
            {
                if (frameAvail)
                {
                    countpaint++;
#if (debug)
                        sw.Reset();
                        sw.Start();
#endif
                    g.DrawImage(this.Img, leftTop.X, leftTop.Y, img_size.Width, img_size.Height);
#if (debug)
                        g.FillRectangle(Brushes.White, new Rectangle(0, 0, 50, 80));
                        g.DrawString(sw.ElapsedMilliseconds.ToString(), f, b, p);
                        g.DrawString(res.ToString(), f, b, p2);
                        g.DrawString(countres.ToString(), f, b, p3);
                        g.DrawString((missedFrame).ToString(), f, b, p4);
                        sw.Stop();
#endif      
                    // this.Img = null;
                    frameAvail = false;
                }
                try
                {

                    Thread.Sleep(0);
                }
                catch (ThreadInterruptedException) { }
            }
            Thread.CurrentThread.Abort();
        }

        void SubForm_Resize(object sender, EventArgs e)
        {
            countres++;
            img_size = this.ClientSize;
            if (img_size.Width / this.ratio < img_size.Height)
            {
                img_size.Height = (int)(img_size.Width / this.ratio);
                leftTop.Y = (int)((this.ClientSize.Height - img_size.Width / this.ratio) / 2.0);
                leftTop.X = 0;
            }
            else
            {
                img_size.Width = (int)(img_size.Height * this.ratio);
                leftTop.X = (int)((this.ClientSize.Width - img_size.Height * this.ratio) / 2.0);
                leftTop.Y = 0;
            }

            // limit image size
            if (img_size.Width > orig_size.Width)
            {
                img_size = orig_size;
                leftTop.X = (int)((this.ClientSize.Width - img_size.Height * this.ratio) / 2.0);
                leftTop.Y = (int)((this.ClientSize.Height - img_size.Width / this.ratio) / 2.0);
            }
        }

        private Image current_image;
        private Size img_size, orig_size;
        public Image Img
        {
            set
            {
                if (value != null)
                {
                    if (ratio == 0)
                    {
                        orig_size = value.Size;
                        ratio = value.Width / (float)(value.Height);
                        SubForm_Resize(null, null);
                    }
                    countframe++;
#if debug
                    sw.Reset();
                    sw.Start();
#endif
                    this.current_image = value;
#if debug
                    res= sw.ElapsedMilliseconds;
                    sw.Stop();
                    if (this.frameAvail) missedFrame++;
#endif
                    this.frameAvail = true;
                    this.paintThread.Interrupt();
                }
            }
            get { return this.current_image; }
        }

        public void Trigger()
        {
            this.Visible = true;
            SubForm_Resize(null, null);
            paintThread.Interrupt();
            if (paintThread.ThreadState == System.Threading.ThreadState.Stopped)
                paintThread = newPaintThread();
            paintThread.Start();
        }

        public event EventHandler ReturnVideo;

        private void SubForm_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData == Keys.Escape)
            {
                this.Visible = false;
                if (ReturnVideo != null)
                    ReturnVideo(this, null);
            }
        }

        private void SubForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = true;
            this.Visible = false;
            if (ReturnVideo != null)
                ReturnVideo(this, null);
        }
    }
}
